#include "dragabletab.h"
#include "ui_dragabletab.h"

#include <QMouseEvent>
#include <QDrag>
#include <QMimeData>
#include <QPainter>
#include <QGraphicsDropShadowEffect>
#include <QStyleOption>
#include <QMainWindow>

#include "toolutils.h"

DragableTab::DragableTab(QString titleText, TabType tabType, QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::DragableTab)
    , mTabType(tabType)
{
    setAttribute(Qt::WA_DeleteOnClose);
    ui->setupUi(this);
    // this->setEnabled(true);
    // this->setDisabled(false);
    if (!titleText.isEmpty()) {
        ui->label->setText(titleText);
    }
    //
    this->setStyleSheet(ToolUtils::ReadStyleSheet(":/qss/defaultTabUi.qss"));
    connect(ui->pushButton, &QPushButton::clicked, this, &DragableTab::ClickButtonToClose);
}

DragableTab::~DragableTab()
{
    delete ui;
}

QLabel* DragableTab::TitleLabel() const
{
    return ui->label;
}

QPushButton* DragableTab::CloseButton() const
{
    return ui->pushButton;
}

DragableTab::TabType DragableTab::ContentType() const
{
    return mTabType;
}

void DragableTab::SetFilePath(QString filePath)
{
    mFilePath = filePath;
}

QString DragableTab::FilePath()
{
    return mFilePath;
}

void DragableTab::ClickButtonToClose()
{
    emit closeFromButton();
}

std::tuple<int, int, int> DragableTab::GetIndex()
{
    return mIndex;
}

void DragableTab::SetIndex(int DIndex, int PIndex, int Tindex)
{
    mIndex = std::make_tuple(DIndex, PIndex, Tindex);
}

void DragableTab::SetTabsScrollArea(TabsScrollArea* tabsScrollArea)
{
    mTabsScrollArea = tabsScrollArea;
}

TabsScrollArea* DragableTab::GetTabsScrollArea()
{
    return mTabsScrollArea;
}

void DragableTab::leaveEvent(QEvent * event)
{
    // 如果拖拽该组件，拖拽开始时，也会收到leaveEvent事件，清理掉它的style
    // qDebug() << "DragableTab::leaveEvent";
    this->ui->pushButton->setStyleSheet("");
    QWidget::leaveEvent(event);
}

void DragableTab::mousePressEvent(QMouseEvent *event)
{
    // qDebug("DragableTab::mousePressEvent");
    if (!(event->buttons() & Qt::LeftButton)) {
        qDebug("DragableTab::mousePressEvent, return");
        QWidget::mousePressEvent(event);
        return;
    }
    emit clicked();
    mDragStartPos = event->pos();
    mDragReady = true;
    this->update();
    event->accept();
}

void DragableTab::mouseMoveEvent(QMouseEvent *event)
{
    // qDebug("DragableTab::mouseMoveEvent");
    if (!mDragReady || !(event->buttons() & Qt::LeftButton)) {
        QWidget::mouseMoveEvent(event);
        return;
    }
    if ((event->pos() - mDragStartPos).manhattanLength() < QApplication::startDragDistance()) {
        QWidget::mouseMoveEvent(event);
        return;
    }
    mDragReady = false;
    this->update();
    auto drag = new QDrag(this);
    auto mimeData = new QMimeData();

    // 设置拖拽数据
    // mimeData->setText(ui->label->text());
    // 放入tab所处(widget_xx, pages_xx, tab_xx) -> (x, y, z)
    mimeData->setData("application/tab-data", QByteArray(
        std::to_string(std::get<0>(mIndex)) + "," + std::to_string(std::get<1>(mIndex)) + "," + std::to_string(std::get<2>(mIndex))));
    drag->setMimeData(mimeData);

    // 设置拖拽图标和热点
    QPixmap pixmap(size());
    pixmap.fill(QColor::fromRgb(60, 60, 60));
    QPainter painter(&pixmap);
    painter.drawRect(pixmap.rect());
    painter.setPen(Qt::white);
    painter.drawText(rect(), Qt::AlignCenter, ui->label->text());
    drag->setPixmap(pixmap);
    drag->setHotSpot(QPoint(0, 0));

    // 添加自定义视觉效果
    auto shadowEffect = new QGraphicsDropShadowEffect(this);
    shadowEffect->setBlurRadius(15);
    shadowEffect->setColor(Qt::black);
    this->setGraphicsEffect(shadowEffect);

    // 执行拖拽操作
    // qDebug("dragIn, mIndex=(%d, %d, %d)", std::get<0>(mIndex), std::get<1>(mIndex), std::get<2>(mIndex));
    Qt::DropAction result = drag->exec(Qt::MoveAction);
    // 移除自定义视觉效果
    this->setGraphicsEffect(nullptr);
    // 三种拖拽结果，由用户去完成后续的数据处理!!!
    if (result != Qt::MoveAction) {
        // 这里需要检测是否处于主窗口内
        if (ToolUtils::IsCursorInWindow()) {
            qDebug("dragOut, isInWindow = false");
            return;
        }
        // 通知到pagesWidgets 删除page 并 通知到dropWidget去生成一个新页面
        emit NeedFlatPage(mIndex);
    }
    // qDebug("dragOut, mIndex=(%d, %d, %d)", std::get<0>(mIndex), std::get<1>(mIndex), std::get<2>(mIndex));
    emit dragOut(mIndex);
}

void DragableTab::mouseReleaseEvent(QMouseEvent *event)
{
    // qDebug("DragableTab::mouseReleaseEvent");
    if (event->button() != Qt::LeftButton) {
        return;
    }
    // 将pressed时的
    ui->pushButton->setStyleSheet("");
    mDragReady = false;
    this->update();
    QWidget::mouseReleaseEvent(event);
}


void DragableTab::dragEnterEvent(QDragEnterEvent *event)
{
    // qDebug() << "DragableTab::dragEnterEvent";
    if (event->mimeData()->hasFormat("application/tab-data") || event->mimeData()->hasFormat("application/tabsScrollArea-data")) {
        event->acceptProposedAction();
    }
}

void DragableTab::paintEvent(QPaintEvent* event)
{
    QStyleOption opt;
    opt.initFrom(this);
    QPainter painter(this);
    if (mDragReady) {
        opt.state |= QStyle::State_Sunken;
        ui->pushButton->setStyleSheet("QPushButton {background-color: rgb(60, 60, 60)}");
    }
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
}

bool DragableTab::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::FocusIn) {
        qDebug("DragableTab::eventFilter, QEvent::FocusIn");
        emit clicked();
    }
    return QWidget::eventFilter(watched, event);
}
